package org.nebula.contrib.ngbatis.binding;

// Copyright (c) 2022 All project authors. All rights reserved.
//
// This source code is licensed under Apache 2.0 License.

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.nebula.contrib.ngbatis.ArgNameFormatter;
import org.nebula.contrib.ngbatis.utils.KeySymbolMap;
import org.springframework.stereotype.Component;

/**
 * 查询语句的中，下划线参数占位符的渲染器 FIXME 当前值支持一次 . 运算，需要修改格式化规则，形成不限制次数的 . 运算符运算
 *
 * @author yeweicheng
 * <br>Now is history!
 */
@Component
public class UnderlineArgNameFormatter implements ArgNameFormatter {

  private static String textFormat(String text, Map<String, Object> obj) {
    Pattern compile = Pattern.compile("\\{\\s{0,}\\w{0,}.\\w{0,}\\s{0,}\\}");
    Matcher matcher = compile.matcher(text);
    Map<String, Integer> elCount = new HashMap<>();
    while (matcher.find()) {
      String target = matcher.group();
      String key = target.split("\\.")[0].replace("{", "").trim();

      if (obj.get(key) instanceof Collection) {
        String countKey = target.replaceAll("\\s{0,}", "");
        Integer integer = elCount.get(countKey);
        if (integer == null) {
          integer = 0;
        }
        text = text.replaceFirst(replaceRegExpSymbol(target),
          target.replaceAll("\\.", "_" + integer + "_"));
        elCount.put(countKey, integer + 1);
      } else {
        text =
          text.replaceFirst(replaceRegExpSymbol(target), target.replaceAll("\\.", "_"));
      }
    }
    return text;
  }

  public static String replaceRegExpSymbol(String text) {
    return text.replace("{", "\\{")
      .replace("}", "\\}");
  }

  @Override
  public CqlAndArgs format(String oldText, Map<String, Object> obj) {
    String newText = textFormat(oldText, obj);
    return new CqlAndArgs(newText, argObjRename(obj));
  }

  public Map<String, Object> argObjRename(Map<String, Object> obj) {
    return new KeySymbolMap(obj, "_").getOneDMap();
  }

}
